#!/usr/bin/env python3
"""
内存缓存查看器
用于查看应用程序内存中的缓存数据
"""

import asyncio
import json
import requests
from datetime import datetime

class MemoryCacheViewer:
    def __init__(self, base_url="http://localhost:8000"):
        self.base_url = base_url
        
    def check_server_status(self):
        """检查服务器状态"""
        try:
            response = requests.get(f"{self.base_url}/health", timeout=5)
            if response.status_code == 200:
                print("✅ 服务器运行正常")
                return True
            else:
                print(f"❌ 服务器响应异常: {response.status_code}")
                return False
        except Exception as e:
            print(f"❌ 无法连接到服务器: {e}")
            return False
    
    def get_market_service_status(self):
        """获取大盘服务状态"""
        try:
            response = requests.get(f"{self.base_url}/api/market/status")
            if response.status_code == 200:
                result = response.json()
                if result.get('success'):
                    status = result['data']
                    print("\n📊 大盘数据服务状态:")
                    print("=" * 50)
                    print(f"🔄 运行状态: {'运行中' if status['running'] else '已停止'}")
                    print(f"🔗 Redis连接: {'已连接' if status['redis_connected'] else '未连接'}")
                    print(f"📈 指数数量: {status['indices_count']}")
                    print(f"⏰ 最后更新: {status['last_update']}")
                    
                    # 如果Redis未连接，说明使用内存缓存
                    if not status['redis_connected']:
                        print("\n💾 当前使用内存缓存模式")
                        self.show_memory_cache_data()
                    else:
                        print("\n🔗 当前使用Redis缓存")
                        
                else:
                    print("❌ 获取状态失败")
            else:
                print(f"❌ 请求失败: {response.status_code}")
        except Exception as e:
            print(f"❌ 获取状态失败: {e}")
    
    def show_memory_cache_data(self):
        """显示内存缓存数据"""
        try:
            # 获取大盘数据（如果Redis未连接，会从内存获取）
            response = requests.get(f"{self.base_url}/api/market/indices")
            if response.status_code == 200:
                result = response.json()
                if result.get('success'):
                    data = result['data']
                    print("\n📊 内存缓存中的大盘数据:")
                    print("=" * 80)
                    
                    for code, index_data in data.items():
                        name = index_data.get('name', '未知')
                        current = index_data.get('current', '0')
                        change_percent = index_data.get('change_percent', '0')
                        timestamp = index_data.get('timestamp', '')
                        
                        print(f"📈 {code} - {name}")
                        print(f"   💰 当前价格: {current}")
                        print(f"   📊 涨跌幅: {change_percent}%")
                        print(f"   ⏰ 时间: {timestamp}")
                        print()
                else:
                    print("❌ 获取数据失败")
            else:
                print(f"❌ 请求失败: {response.status_code}")
        except Exception as e:
            print(f"❌ 获取内存数据失败: {e}")
    
    def show_realtime_service_status(self):
        """显示实时服务状态"""
        try:
            response = requests.get(f"{self.base_url}/api/realtime/status")
            if response.status_code == 200:
                result = response.json()
                if result.get('success'):
                    status = result['data']
                    print("\n📱 实时股价服务状态:")
                    print("=" * 50)
                    print(f"🔄 运行状态: {'运行中' if status['running'] else '已停止'}")
                    print(f"📱 WebSocket连接数: {status['connections']}")
                    print(f"📊 订阅股票数: {status['subscribed_stocks']}")
                    
                    if status['subscribed_stocks'] > 0:
                        print(f"📈 订阅列表: {', '.join(status.get('stock_list', []))}")
                else:
                    print("❌ 获取实时服务状态失败")
            else:
                print(f"❌ 请求失败: {response.status_code}")
        except Exception as e:
            print(f"❌ 获取实时服务状态失败: {e}")
    
    def test_memory_fallback(self):
        """测试内存回退机制"""
        print("\n🧪 测试内存回退机制:")
        print("=" * 50)
        print("💡 说明: 当Redis连接失败时，系统会自动使用内存缓存")
        print("📊 内存缓存位置:")
        print("   1. 大盘数据: MarketIndexService.market_data (字典)")
        print("   2. 实时数据: 直接生成，不缓存 (每次请求重新生成)")
        print("   3. 用户数据: SQLite数据库 (持久化存储)")
        print()
        print("🔄 数据流程:")
        print("   Redis可用 → 优先使用Redis缓存")
        print("   Redis不可用 → 自动回退到内存/直接生成")
        print()
        
        # 获取当前数据来源
        try:
            response = requests.get(f"{self.base_url}/api/market/status")
            if response.status_code == 200:
                result = response.json()
                if result.get('success'):
                    redis_connected = result['data']['redis_connected']
                    if redis_connected:
                        print("✅ 当前数据来源: Redis缓存")
                        print("💾 内存缓存作为备份存在")
                    else:
                        print("⚠️ 当前数据来源: 内存缓存")
                        print("🔗 Redis连接失败，已自动回退")
        except Exception as e:
            print(f"❌ 检查数据来源失败: {e}")
    
    def show_cache_architecture(self):
        """显示缓存架构"""
        print("\n🏗️ 系统缓存架构:")
        print("=" * 80)
        print("""
📊 数据存储层次:
┌─────────────────────────────────────────────────────────────┐
│                    应用程序内存                              │
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐ │
│  │   WebSocket     │  │  订阅股票列表    │  │   服务状态      │ │
│  │   连接池        │  │  Set[str]       │  │   Dict         │ │
│  └─────────────────┘  └─────────────────┘  └─────────────────┘ │
│                                                              │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │           大盘数据内存缓存                               │ │
│  │        MarketIndexService.market_data                   │ │
│  │              Dict[str, Dict]                           │ │
│  └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
                              ↕️
┌─────────────────────────────────────────────────────────────┐
│                    Redis缓存 (端口6380)                     │
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐ │
│  │  market_index:* │  │  realtime:*     │  │ market_history:*│ │
│  │   (哈希数据)     │  │  (字符串+TTL)   │  │   (列表数据)    │ │
│  └─────────────────┘  └─────────────────┘  └─────────────────┘ │
└─────────────────────────────────────────────────────────────┘
                              ↕️
┌─────────────────────────────────────────────────────────────┐
│                SQLite数据库 (data/stock_data.db)            │
│  ┌─────────────────┐  ┌─────────────────┐                   │
│  │ stock_financial │  │     users       │                   │
│  │   (财务数据)     │  │   (用户数据)    │                   │
│  └─────────────────┘  └─────────────────┘                   │
└─────────────────────────────────────────────────────────────┘

🔄 数据流向:
1. 实时数据 → Redis缓存 → 内存备份
2. 财务数据 → SQLite数据库 (永久存储)
3. 用户数据 → SQLite数据库 (永久存储)
        """)

def main():
    viewer = MemoryCacheViewer()
    
    if not viewer.check_server_status():
        print("请先启动服务器: python run.py")
        return
    
    while True:
        print("\n" + "="*60)
        print("🧠 内存缓存查看器")
        print("="*60)
        print("1. 查看大盘服务状态")
        print("2. 查看实时服务状态")
        print("3. 显示内存缓存数据")
        print("4. 测试内存回退机制")
        print("5. 显示缓存架构")
        print("0. 退出")
        print("="*60)
        
        choice = input("请选择操作 (0-5): ").strip()
        
        if choice == "0":
            break
        elif choice == "1":
            viewer.get_market_service_status()
        elif choice == "2":
            viewer.show_realtime_service_status()
        elif choice == "3":
            viewer.show_memory_cache_data()
        elif choice == "4":
            viewer.test_memory_fallback()
        elif choice == "5":
            viewer.show_cache_architecture()
        else:
            print("❌ 无效选择")
        
        input("\n按回车键继续...")

if __name__ == "__main__":
    main()
